﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using FinWeb3.Models.Helpers;
using FinWeb3.Models;
using FinWeb3.Models.ModelView;
using FinWeb3.Models.Repository;

namespace FinWeb3.Controllers
{
    [HandleError]
    [Authorize(Roles = "finwebuser")]
    public class HomeController : Controller
    {
        private BankManager bankManager;
        private BillManager billManager;
        private GroupManager groupManager;
        private StatementManager statementManager;


        public HomeController() : base()
        {
            SetupManagers();
        }

        private void SetupManagers()
        {
            if (User != null)
            {
                var user = User.Identity;
                var billRepository = new BillRepository();
                var bankRepository = new BankRepository();
                var groupRepository = new GroupRepository();
                var statementRepository = new StatementRepository();

                bankManager = new BankManager(bankRepository, user);
                billManager = new BillManager(billRepository, groupRepository, user);
                groupManager = new GroupManager(groupRepository, billRepository, user);
                statementManager = new StatementManager(statementRepository, bankRepository, user);
            }
        }



        public ActionResult Index()
        {
            return RedirectToAction("Bills", new { fromdate = DateTime.Today.FirstDay().ToDateId(), todate = DateTime.Today.LastDay().ToDateId() });
        }

        public ActionResult Bills(string fromdate, string todate)
        {
            SetupManagers();

            var details = new AccountInfoModelView(fromdate, todate);

            details.Bills = billManager.Get(details.ToDate, BillList.NotPayed).ToList();
            details.Banks = bankManager.GetAll();
            details.StatementManager = statementManager;
            details.TotalByCategories = billManager.GetTotals(details.FromDate, details.ToDate);
            details.WalletValue = billManager.GetWalletValue();

            if (TempData.ContainsKey("msg"))
                details.Message = TempData["msg"].ToString();

            TempData["billsTtile"] = "(em aberto)";

            return View("Index", details);
        }

        public ActionResult ByCategory(string fromdate, string todate, string category)
        {
            SetupManagers();

            var details = new AccountInfoModelView(fromdate, todate);

            details.Bills = billManager.Get(details.FromDate, details.ToDate, BillList.All, true).Where(x => x.Category == category && x.HasDetailList == false).ToList();
            details.Banks = bankManager.GetAll();
            details.StatementManager = statementManager;
            details.TotalByCategories = billManager.GetTotals(details.FromDate, details.ToDate);
            details.WalletValue = billManager.GetWalletValue();

            if (TempData.ContainsKey("msg"))
                details.Message = TempData["msg"].ToString();

            TempData["billsTtile"] = "(categoria: " + HttpUtility.HtmlEncode(category) + ")";

            return View("Index", details);
        }

        public ActionResult EditBill(string fromdate, string todate, int id)
        {
            SetupManagers();

            var details = new EditAccountDataModelView(fromdate, todate);
            details.EditedBill = billManager.Get(id);

            return View(details);
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult EditBill(EditAccountDataModelView data)
        {
            SetupManagers();

            billManager.Save(data.EditedBill);

            return RedirectToAction("Bills", new { fromdate = data.FromDate.ToDateId(), todate = data.ToDate.ToDateId() });
        }

        public ActionResult AddBill(string fromdate, string todate)
        {
            var details = new BillModelView(fromdate, todate);
            details.Day = DateTime.Today;

            return View(details);
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult AddBill(BillModelView bill)
        {
            SetupManagers();

            billManager.Save(bill);

            TempData["msg"] = "Conta cadastrada.";

            return RedirectToAction("Bills", new { fromdate = bill.FromDate.ToDateId(), todate = bill.ToDate.ToDateId() });
        }

        public ActionResult DeleteBill(string fromdate, string todate, int id)
        {
            SetupManagers();

            billManager.Delete(id);

            TempData["msg"] = string.Format("Conta excluida. <a href='/Home/UndoDeleteBill/{0}/{1}/{2}'>Desfazer</a>",
                fromdate, todate, id);

            return RedirectToAction("Bills", new { fromdate = fromdate, todate = todate });
        }

        public ActionResult PayBill(string fromdate, string todate, int id)
        {
            SetupManagers();

            billManager.Pay(id);

            TempData["msg"] = string.Format("Conta marcada como paga. <a href='/Home/UndoPayBill/{0}/{1}/{2}'>Desfazer</a>",
                fromdate, todate, id);

            return RedirectToAction("Bills", new { fromdate = fromdate, todate = todate });
        }

        public ActionResult UndoDeleteBill(string fromdate, string todate, int id)
        {
            SetupManagers();

            billManager.UndoDelete(id);

            TempData["msg"] = "Exclusão desfeita.";

            return RedirectToAction("Bills", new { fromdate = fromdate, todate = todate });
        }

        public ActionResult UndoPayBill(string fromdate, string todate, int id)
        {
            SetupManagers();

            billManager.UndoPay(id);
            TempData["msg"] = "Pagamento desfeito.";

            return RedirectToAction("Bills", new { fromdate = fromdate, todate = todate });
        }



        public ActionResult DetachDetail(string fromdate, string todate, int idBill, int idDetail)
        {
            SetupManagers();

            billManager.DetachDetailLine(idDetail);

            return RedirectToAction("AddDetail", new { fromdate = fromdate, todate = todate, id = idBill });
        }

        public ActionResult AddDetail(string fromdate, string todate, int id)
        {
            SetupManagers();

            var details = new BillDetailModelView(fromdate, todate);
            details.BillId = id;
            details.Bill = billManager.Get(id);
            details.Lines = billManager.GetDetailLine(id);
            details.NewDetail = new Bill();
            details.NewDetail.Day = DateTime.Today;

            return View(details);
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult AddDetail(BillDetailModelView detail)
        {
            SetupManagers();

            billManager.SaveDetailLine(detail);

            return RedirectToAction("AddDetail", new { fromdate = detail.FromDate.ToDateId(), todate = detail.ToDate.ToDateId(), id = detail.BillId });
        }


        public ActionResult DynamicCrud(string fromdate, string todate)
        {
            var details = new BasicModelView(fromdate, todate);
            return View(details);
        }

        // crud
        public ActionResult EditBank(string fromdate, string todate, int id)
        {
            SetupManagers();

            var details = new EditAccountDataModelView(fromdate, todate);
            details.EditedBank = bankManager.Get(id);

            return View(details);
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult EditBank(EditAccountDataModelView data)
        {
            SetupManagers();

            bankManager.Save(data.EditedBank);

            return RedirectToAction("Bills", new { fromdate = data.FromDate.ToDateId(), todate = data.ToDate.ToDateId() });
        }


        public ActionResult EditGroup(string fromdate, string todate, int id)
        {
            SetupManagers();

            var details = new EditAccountDataModelView(fromdate, todate);
            details.EditedGroup = groupManager.Get(id);

            return View(details);
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult EditGroup(EditAccountDataModelView data)
        {
            SetupManagers();

            groupManager.Save(data.EditedGroup);

            return RedirectToAction("Bills", new { fromdate = data.FromDate.ToDateId(), todate = data.ToDate.ToDateId() });
        }

        public ActionResult DeleteGroup(string fromdate, string todate, int id)
        {
            SetupManagers();

            groupManager.Delete(id);

            TempData["msg"] = "Grupo excluido.";

            return RedirectToAction("Bills", new { fromdate = fromdate, todate = todate });
        }
    }
}
